import threadPool.ThreadFactory.MyExceptionThreadFactory;

import java.util.concurrent.*;

/**
 * 线程池创建提供了切面，用于线程执行前，所有线程执行后，终止后回调的方法 brforeExecute，afterExecute,terminate
 */
public class BeforAfterTerminatedTest {
    /**
     * 在线程执行前，执行后增加切面，在线程池关闭时执行某段程序
     * 需要实现自己的线程池类，并覆写brforeExecute，afterExecute,terminate方法
     */
    public static void main(String[] args) {
        MyExceptionThreadFactory threadFactory = new MyExceptionThreadFactory("myThreadFactory",true);
        ThreadPoolExecutorDemo threadPoolExecutorDemo = new ThreadPoolExecutorDemo(2,2,
                Integer.MAX_VALUE, TimeUnit.SECONDS,new LinkedBlockingDeque<>(),threadFactory);
        threadPoolExecutorDemo.execute(new RunnerDemo("A1"));
        threadPoolExecutorDemo.execute(new RunnerDemo("A2"));
        threadPoolExecutorDemo.execute(new RunnerDemo("A3"));
        threadPoolExecutorDemo.execute(new RunnerDemo("A4"));
        threadPoolExecutorDemo.shutdown();
    }

}
class ThreadPoolExecutorDemo extends ThreadPoolExecutor{



    // 线程执行前切面
    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        System.out.println(" before " + ((RunnerDemo) r).getName()  + "run....");
    }
    // 线程执行后切面
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        System.out.println(" after " + ((RunnerDemo) r).getName()  + "run....");
    }

    @Override
    protected void terminated() {
        super.terminated();
        System.out.println(" terminated " + "....");
    }


    public ThreadPoolExecutorDemo(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public ThreadPoolExecutorDemo(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public ThreadPoolExecutorDemo(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    public ThreadPoolExecutorDemo(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }
}
class RunnerDemo implements Runnable{
    private String name;

    public RunnerDemo(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("System.currentTimeMillis() = " + System.currentTimeMillis());

    }
}

